package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceCode;
import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryAttributeTemplateMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.CategoryUpdateNewDTO;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;



@Service
@Slf4j
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.debug("开始处理【添加品牌】的业务：{}", categoryAddNewDTO);
        //调用mapper对象的根据名称统计数量方法进行统计
        //判断统计结果是否大于0
        //是:名称已经占用 ,抛出异常
        String name = categoryAddNewDTO.getName();
        int count = categoryMapper.countByName(name);
        if (count>0){
            String message = "添加类别失败,类别名称已经被占用!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        log.trace("品牌名称没有被占用，继续向后执行……");

        //声明局部变量depth,默认值为1
        //取出参数中的parentId,
        //判断是否不为0;
        // 是：调用Mapper对象的【根据id查询详情】，使用parentId作为参数，执行查询
        // -- 判断查询结果是否不为null
        // -- 是：局部变量depth=父级depth+1
        // -- 否：父级类别不存在，抛出异常（NOT_FOUND）
        CategoryStandardVO parentCategory = null;
        Integer depth = 1;
        Long parentId = categoryAddNewDTO.getParentId();
        if (parentId!=0){
            log.trace("当前选择了父级类别……");
            parentCategory = categoryMapper.getStandardById(parentId);
            log.trace("从数据库中查询父级类别为：{}", parentCategory);
            if (parentCategory!=null){
                depth=parentCategory.getDepth()+depth;
                log.trace("计算得到当前尝试添加的类别的深度：{}", depth);
            }else {
                String message = "父级类别不存在!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
            }


        }
        // 创建Category实体类的对象
        // 将参数DTO的各属性值复制到Category实体类对象中
        // 补全Category实体类对象的属性：depth
        // 补全Category实体类对象的属性：is_parent：固定为0
        // 调用Mapper对象的方法，将数据插入到数据库，并获取返回值
        // 判断返回值是否不为1
        // 是：抛出异常（ERR_INSERT）

        Category category = new Category();
        BeanUtils.copyProperties(categoryAddNewDTO,category);
        category.setDepth(depth);
        category.setIsParent(0);
        log.debug("准备向数据库中写入类别数据：{}", category);
        int rows = categoryMapper.insert(category);
        if (rows!=1){
            String message = "插入类别失败,服务器忙,请稍后重试!!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        // 判断parentId是否不为0
        // 是：判断父级类别的isParent是否为0
        // -- 是：创建新的Category对象，封装：parentId，isParent(1)
        // -- -- 调用Mapper对象的【更新】方法，执行修改数据，并获取返回值
        // -- -- 判断返回值是否不为1
        // -- -- -- 是：抛出异常（ERR_UPDATE）

        if (parentId!=0){
            if (parentCategory.getIsParent()==0){
                log.trace("准备更新父级类别的isParent值……");
                Category updateParentCategory = new Category();
                updateParentCategory.setId(parentId);
                updateParentCategory.setIsParent(1);
                int updateRows = categoryMapper.updateById(updateParentCategory);
                if (updateRows != 1) {
                    // 是：抛出异常（ERR_UPDATE）
                    String message = "添加类别失败，服务器忙，请稍后再尝试！";
                    log.warn(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
                log.trace("更新父级类别的数据完成");

            }
        }

    }

    @Override
    public void deleteById(Long id) {
        //根据id查询要删除的类别数据是否存在
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        //如果不存在 为null 抛出异常
        if (currentCategory==null){
            String message = "删除类别数据失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //若果数据存在 还要判断要删除的数据是否为父级 若是父级则不能删除
        //根据isParent判断该数据是否为父级
        //是 尝试删除的数据为父级 不能删除 抛出异常
        if (currentCategory.getIsParent()==1){
            String message = "删除失败,尝试删除的数据为父级!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //调用ctegoryMapper的countByCategoryId 统计类别关联数据的数量
        //如果大于0 则代表 有关联数据 不能删除 抛出异常
        int count= brandCategoryMapper.countByCategoryId(id);
        log.debug("统计数量:{}",count);
        if (count>0){
            String message ="删除失败,存在与品牌关联的数据";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //调用categoryAttributeTemplateMapper中的countByCategoryId方法统计与类别关联数据的数量
        //如果大于0 则代表 有关联数据 不能删除 抛出异常
         count = categoryAttributeTemplateMapper.countByCategoryId(id);
        log.debug("统计数量:{}",count);
        if (count>0){
            String message ="删除失败,存在与类别属性模板关联的数据";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //调用spuMapper中的countByCategoryId方法统计与类spu关联数据的数量
        //如果大于0 则代表 有关联数据 不能删除 抛出异常
        count= spuMapper.countByCategoryId(id);
        log.debug("统计数量:{}",count);
        if (count>0){
            String message ="删除失败,存在与spu关联的数据";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }


        //调用mapper对象的根据id删除的方法执行删除,并获取返回值
        //判断返回值是否不为1
        //是 抛出异常
        int rows = categoryMapper.deleteById(id);
        if (rows!=1){
            String message = "删除类别数据失败,服务器忙,请稍后重试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE,message);
        }
        //判断删除的数据是否是父级中的最后一个子集
        //如果是 则把父级中的isParent改为0
        //从当前要删除的数据中获取parentId
        //调用mapper的countByParentId(parentId)进行统计
        // 判断统计结果是否为0
        // 创建新的Category对象，用于更新父级，此Category对象中需要封装：id（parentId），isParent（0）
        // 调用Mapper对象的【更新】功能，执行修改数据，并获取返回值
        // 判断返回值是否不为1
        // 是：抛出异常（ERR_UPDATE）
        Long parentId = currentCategory.getParentId();
        if(parentId!=0){
             count = categoryMapper.countByParentId(parentId);
            if (count==0){
                Category category = new Category();
                category.setId(parentId);
                category.setIsParent(0);
                 rows = categoryMapper.updateById(category);
                if (rows!=1){
                    String message = "修改类别数据失败,服务器忙,请稍后重试!";
                    log.warn(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE,message);
                }
            }
        }
    }

    @Override
    public void setEnable(Long id) {
        //调用mapper中的查询详情方法 判断是否存在该数据
        //如果不存在抛出异常
        CategoryStandardVO standardById = categoryMapper.getStandardById(id);
        log.debug("根据id={},查询到的数据={}",id,standardById);
        if (standardById==null){
            String message = "启用类别失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //根据详情查看该类别是否已经是启用状态
        //如果是 则抛出异常
        if (standardById.getEnable()==1){
            String message = "启用类别失败,该类别已经是启用状态!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //创建Category对象 封装id和enable
        //修改类别的状态为启用状态
        Category category = new Category();
        category.setId(id);
        category.setEnable(1);
        log.debug("即将修改的category:{}",category);
        int rows = categoryMapper.updateById(category);
        log.debug("生效的行数={}",rows);
        //判断 rows是否不等于一
        //如果是则证明修改失败,抛出异常
        if (rows!=1){
            String message = "启用类别失败,服务器忙,请稍后重试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public void setDisable(Long id) {
        //调用mapper中的查询详情方法 判断是否存在该数据
        //如果不存在抛出异常
        CategoryStandardVO standardById = categoryMapper.getStandardById(id);
        log.debug("根据id={},查询到的数据={}",id,standardById);
        if (standardById==null){
            String message = "启用类别失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //根据详情查看该类别是否已经是禁用状态
        //如果是 则抛出异常
        if (standardById.getEnable()==0){
            String message = "禁用类别失败,该类别已经是禁用状态!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //创建Category对象 封装id和enable
        //修改类别的状态为启用状态
        Category category = new Category();
        category.setId(id);
        category.setEnable(0);
        log.debug("即将修改的category:{}",category);
        int rows = categoryMapper.updateById(category);
        log.debug("生效的行数={}",rows);
        //判断 rows是否不等于一
        //如果是则证明修改失败,抛出异常
        if (rows!=1){
            String message = "禁用类别失败,服务器忙,请稍后重试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public void setDisplay(Long id) {
        //调用mapper方法中的查询标准信息
        //根据id判断当前的数据是否存在
        //如果不存在则抛出异常 存在则继续
        CategoryStandardVO standardById = categoryMapper.getStandardById(id);
        log.debug("根据id={},查询到的数据={}",id,standardById);
        if (standardById==null){
            String message = "显示类别失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //判断当前数据是否已经是显示状态
        //如果是 则不能开启显示 抛出异常
        //如果不是 则继续
        if(standardById.getIsDisplay()==1){
            String message = "显示类别失败,该类别已经是显示状态!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //创建category对象 封装id和isDisplay
        //调用mapper中的修改数据方法 开启显示
        Category category = new Category();
        category.setId(id);
        category.setIsDisplay(1);
        log.debug("即将修改的category:{}",category);
        int rows = categoryMapper.updateById(category);
        log.debug("生效的行数={}",rows);
        //判断 rows是否不等于一
        //如果是则证明修改失败,抛出异常
        if (rows!=1){
            String message = "显示类别失败,服务器忙,请稍后重试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public void setHidden(Long id) {
       //调用mapper方法中的查询标准信息
        //根据id判断当前的数据是否存在
        //如果不存在则抛出异常 存在则继续
        CategoryStandardVO standardById = categoryMapper.getStandardById(id);
        log.debug("根据id={},查询到的数据={}",id,standardById);
        if (standardById==null){
            String message = "显示类别失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        if (standardById.getIsDisplay()==1){
            //创建category对象 封装id和isDisplay
            //调用mapper中的修改数据方法 禁用显示
            Category category = new Category();
            category.setId(id);
            category.setIsDisplay(0);
            log.debug("即将修改的category:{}",category);
            int rows = categoryMapper.updateById(category);
            log.debug("生效的行数={}",rows);
            //判断 rows是否不等于一
            //如果是则证明修改失败,抛出异常
            if (rows!=1){
                String message = "隐藏类别失败,服务器忙,请稍后重试!";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_UPDATE,message);
            }
        }else {
            String message = "隐藏类别失败,该类别已经是隐藏状态!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

    }

    @Override
    public void update(CategoryUpdateNewDTO categoryUpdateNewDTO) {
        log.debug("即将处理修改类别,参数:{}",categoryUpdateNewDTO);
        //获取DTO中的类别id
        //跟据类别id查询详情 看是否存在数据
        //如果不存在 则不能修改 抛出异常
        Long categoryId = categoryUpdateNewDTO.getId();
        log.debug("尝试修改类别的id={}",categoryId);
        CategoryStandardVO standardById = categoryMapper.getStandardById(categoryId);
        log.debug("根据类别id={},查询到的详情={}",categoryId,standardById);
        if (standardById==null){
            String message = "修改类别失败,该数据不存在!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //创建Category对象 ,将DTO中的属性赋值给他
        //调用mapper中的update方法修改类别
        //判断生效的行数是否不等于1
        //如果是 则抛出异常 修改失败
        Category category = new Category();
        BeanUtils.copyProperties(categoryUpdateNewDTO,category);
        log.debug("即将修改的类别={}",category);
        int rows = categoryMapper.updateById(category);
        log.debug("生效的行数:rows={}",rows);
        if (rows!=1){
            String message = "修改失败,服务器忙,请稍后重试!";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }


    }
}
